package com.iflytek.jzcpx.procuracy.tools.ocr;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iflytek.jzcpx.procuracy.tools.ocr.pdf.Rect;
import com.iflytek.jzcpx.procuracy.tools.ocr.pdf.Sent;
import com.iflytek.jzcpx.procuracy.tools.ocr.pdf.Textline;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * OCR工具类
 *
 * @author <a href=mailto:ktyi@iflytek.com>伊开堂</a>
 * @date 2019-08-27 16:03
 */
public class OcrUtil {
    private static final Logger logger = LoggerFactory.getLogger(OcrUtil.class);

    /**
     * 提取文本内容
     *
     * @param ocrResult ocr原始结果
     * @param type      类型 1 原始引擎结果（默认）2 纯文本 3签章 4 手印  5图片 6签名
     *
     * @return 根据type返回不同结果形式
     */
    public static String getTextByType(String ocrResult, String type) {
        StringBuilder result = new StringBuilder();
        if (StringUtils.isNotBlank(ocrResult)) {
            try {
                JSONObject data = JSONObject.parseObject(ocrResult);
                JSONObject taskResult = JSONObject.parseObject(data.getString(OcrConstants.ResultStruct.TASK_RESULT));
                if (taskResult == null) {
                    return null;
                }
                JSONArray pages = JSONObject.parseArray(taskResult.getString(OcrConstants.ResultStruct.PAGE));
                if (pages == null) {
                    return null;
                }
                int size = pages.size();
                for (int j = 0; j < size; j++) {
                    JSONObject page = pages.getJSONObject(j);
                    JSONArray jsonArray = new JSONArray();
                    if (OcrConstants.STR_TWO.equals(type) || OcrConstants.STR_SIX.equals(type)) {
                        //TextRegion
                        extractRegionByName(page, jsonArray, OcrConstants.ResultStruct.TEXT_REGION);
                        //Table
                        extractTableRegion(page, jsonArray);
                        //插图Illustration
                        extractRegionByName(page, jsonArray, OcrConstants.ResultStruct.ILLUSTRATION);
                    }

                    if (OcrConstants.STR_TWO.equals(type) || OcrConstants.STR_THREE.equals(type) || OcrConstants.STR_SIX.equals(type)) {
                        //签章Seal
                        extractRegionByName(page, jsonArray, OcrConstants.ResultStruct.SEAL);
                    }
                    if (OcrConstants.STR_TWO.equals(type) || OcrConstants.STR_FOUR.equals(type) || OcrConstants.STR_SIX.equals(type)) {
                        //手印Fingerprint
                        extractRegionByName(page, jsonArray, OcrConstants.ResultStruct.FINGER_PRINT);
                    }
                    if (OcrConstants.STR_TWO.equals(type) || OcrConstants.STR_FIVE.equals(type) || OcrConstants.STR_SIX.equals(type)) {
                        //图片Graphics
                        extractRegionByName(page, jsonArray, OcrConstants.ResultStruct.GRAPHICS);
                    }
                    if (OcrConstants.STR_SIX.equals(type)) {
                        //签名,手写体HANDWRITE
                        getTextContent(result, jsonArray, OcrConstants.ResultStruct.HANDWRITE);
                    }
                    else if (OcrConstants.STR_TWO.equals(type)) {
                        //提取纯文本
                        getTextContent(result, jsonArray, null);
                    }
                    else {
                        return jsonArray.toJSONString();
                    }
                }
            }
            catch (Exception e) {
                logger.info("文本内容提取错误信息：{}，OCR结果:{}，对应type:{},异常信息:{}", e.getMessage(), ocrResult, type, e);
            }
        }
        return result.toString();
    }

    /**
     * 获取文本内容
     *
     * @param result    保存文本
     * @param jsonArray 区域结果
     */
    protected static void getTextContent(StringBuilder result, JSONArray jsonArray, String extactType) {
        int ksize = jsonArray.size();
        List<Textline> textLines = new ArrayList<Textline>();
        for (int k = 0; k < ksize; k++) {
            JSONObject textRegion = jsonArray.getJSONObject(k);
            if (textRegion == null) {
                continue;
            }
            String textLine = textRegion.getString(OcrConstants.ResultStruct.TEXT_LINE);
            if (StringUtils.isNoneBlank(textLine)) {
                textLines.addAll(JSONObject.parseArray(textLine, Textline.class));
            }
        }
        //纵坐标升序排序
        textLines.sort(Comparator.comparing(Textline::getRect, Comparator.comparing(Rect::getY, (y1, y2) -> {
            return y1 - y2;
        })));
        if (textLines != null && textLines.size() > 0) {
            for (Textline textline : textLines) {
                String type = textline.getType();
                boolean exactHandWrite = OcrConstants.ResultStruct.HANDWRITE.equals(extactType);
                boolean handWrite = OcrConstants.ResultStruct.HANDWRITE.equals(type);
                if ((exactHandWrite && handWrite) || !exactHandWrite) {
                    List<Sent> sents = textline.getSent();
                    if (sents != null && sents.size() > 0) {
                        for (Sent sent : sents) {
                            String value = sent.getValue();
                            result.append(value).append("\n");
                        }
                    }
                }
            }
        }

    }

    /**
     * 抽取表区域
     *
     * @param page      整张图结果
     * @param jsonArray 区域结果
     */
    protected static void extractTableRegion(JSONObject page, JSONArray jsonArray) {
        JSONArray tables = JSONObject.parseArray(page.getString(OcrConstants.ResultStruct.TABLE));
        if (tables != null && tables.size() > 0) {
            int tsize = tables.size();
            for (int t = 0; t < tsize; t++) {
                JSONObject table = tables.getJSONObject(t);
                extractRegionByName(table, jsonArray, OcrConstants.ResultStruct.CELL);
            }
        }
    }

    /**
     * 根据区域名称抽取该区域
     *
     * @param page       整张图结果
     * @param jsonArray  区域结果
     * @param regionName 区域名称
     */
    protected static void extractRegionByName(JSONObject page, JSONArray jsonArray, String regionName) {
        JSONArray graphics = JSONObject.parseArray(page.getString(regionName));
        if (graphics != null && graphics.size() > 0) {
            jsonArray.addAll(graphics);
        }
    }

}
